package org.aksw.xoperator.sparql;

import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * interface for all SPARQL endpoints, whether an external or internal endpoint.
 * @author joerg
 *
 */
public abstract class SparqlEndpoint {
	
	private static Log log = LogFactory.getLog(SparqlEndpoint.class);
	
	ThreadPoolExecutor executor;
	
	public abstract void process(SparqlQuery query);
	
	public abstract List<FutureTask<SparqlResult>> getFuturesFor(SparqlQuery query);
	
	public SparqlEndpoint(ThreadPoolExecutor executor) {
		super();
		this.executor = executor;
	}

	public void processFutures(List<FutureTask<SparqlResult>> futures,int timeout){
		
		//execute them
		for (FutureTask<SparqlResult> futureQuery : futures) {
			executor.execute(futureQuery);
		}
		
		//wait for the remote results
		long start = System.currentTimeMillis();
		for (FutureTask<SparqlResult> futureTask : futures) {

			if(System.currentTimeMillis()-start<timeout){
				try {
					futureTask.get(timeout+start-System.currentTimeMillis(), TimeUnit.MILLISECONDS);
				} catch (InterruptedException e) {
					log.error(" ", e);
				} catch (ExecutionException e) {
					log.error(" ", e);
				} catch (TimeoutException e) {
					log.error(" ", e);
				}
			}
			
		}
	}
	
}
